package com.naiterui.ehp.bs.patient.dao.impl;

import com.naiterui.ehp.bp.domain.*;
import com.naiterui.ehp.bp.utils.lang.StringUtil;
import com.naiterui.ehp.bs.patient.dao.IPatientDao;
import com.naiterui.ehp.bs.patient.repository.IApAttendRepository;
import com.naiterui.ehp.bs.patient.repository.IApPatientPersonDoctorRepository;
import com.naiterui.ehp.bs.patient.repository.IApPatientRepository;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigInteger;
import java.util.*;

/**
 * 患者基础信息持久化实现
 *
 * @version 2015年6月18日 下午5:04:58 by Amber
 * @Description 数据库操作
 */
@Component
public class ApPatientDaoImpl implements IPatientDao {

    @Autowired
    private IApPatientRepository patientRepository;
    @Autowired
    private IApAttendRepository attendRepository;
    @Autowired
    private IApPatientPersonDoctorRepository patientPersonDoctorRepository;

    @Override
    public Patient getPatientByOpenId(String openId) {
        return patientRepository.findFirstByOpenId(openId);
    }

    @Override
    public boolean existAttendRelation(Long patientId, Long doctorId) {
        Integer attends = attendRepository.countByAttendPKPatientIdAndAttendPKDoctorId(patientId, doctorId);
        return null != attends && attends > 0;
    }

    @Override
    public boolean existPersonalRelation(Long patientId, Long doctorId) {
        return this.findPersonalRelation(patientId, doctorId);
    }

    private boolean findPersonalRelation(Long patientId, Long doctorId) {
        Integer num = patientPersonDoctorRepository.countByPersonPKPatientIdAndPersonPKDoctorId(patientId, doctorId);
        return num > 0;
    }

    @Override
    public void cancelAttend(Long patientId, Long doctorId) {
        attendRepository.deleteByAttendPKPatientIdAndAttendPKDoctorId(patientId, doctorId);
    }

    @Override
    public Patient getPatientByUnionId(String unionId) {
        return patientRepository.findFirstByUnionId(unionId);
    }

    @Override
    public List<BigInteger> getPersonalIds(Long patientId, boolean isDisable) {
        List<BigInteger> result = patientRepository.getPersonalIds(patientId);
        // 不含禁用状态医生，只取启用状态医生。否则不过滤改状态
        if (!isDisable) {
            result = patientRepository.getPersonalIdsByAccountStatus(patientId);
        }
        return result;
    }

    @Override
    public List<BigInteger> getPersonalIds(Long patientId) {
        // 取所有非禁用状态私人医生
        return this.getPersonalIds(patientId, false);
    }

    @Override
    public Patient getByPhone(String phoneNum) {
        return patientRepository.findFirstByPhone(phoneNum);
    }

    @Override
    public void addPersonalDoctor(Long doctorId, Long patientId, int source) {
        PatientPersonDoctorPK patientPersonDoctorPK = new PatientPersonDoctorPK(patientId, doctorId);
        PatientPersonDoctor patientPersonDoctor = new PatientPersonDoctor();
        patientPersonDoctor.setPersonPK(patientPersonDoctorPK);
        patientPersonDoctor.setSource(source);
        patientPersonDoctorRepository.save(patientPersonDoctor);
    }

    @Override
    public void attendDoctor(Long doctorId, Long patientId) {
        Attend attend = new Attend(new AttendPK(patientId, doctorId), new Date());
        attendRepository.save(attend);
    }

    @Override
    public void update(Patient patient) {
        patient.setChangedAt(new Date());
        patientRepository.update(patient);
    }

    @Override
    public void saveOrUpdatePatient(Patient patient) {
        patient.setChangedAt(new Date());
        patientRepository.saveOrUpdate(patient);
    }

    @Override
    public Patient getPatient(Long patientId) {
        return patientRepository.get(patientId);
    }

    @Override
    public void updateCancelStatus(String unionId, int cancelStatus) {
        patientRepository.updatePatientByUnionId(unionId, cancelStatus);
    }

    /**
     * 根据手机号获取患者记录
     *
     * @param phone
     *
     * @return
     *
     * @Author fangguanhong
     * @Date 2016-4-11
     * @see com.naiterui.ehp.bs.patient.dao.IPatientDao#getPatientByPhone(java.lang.String)
     * @since 1.0.0
     */
    @Override
    public Patient getPatientByPhone(String phone) {
        return patientRepository.findFirstByPhone(phone);
    }

    @Override
    public Map<Long, Patient> getPatientMap(Set<Long> patientIdSet) {

        Map<Long, Patient> resultMap = new HashMap<>();
        String patiendIdStr = StringUtil.convertCollection(patientIdSet);
        if (StringUtils.isBlank(patiendIdStr)) {
            return resultMap;
        }
        List<Patient> patientList = patientRepository.findByIdIn(patientIdSet);
        if (CollectionUtils.isNotEmpty(patientList)) {
            for (Patient patient : patientList) {
                resultMap.put(patient.getId(), patient);
            }
        }
        return resultMap;
    }

    @Override
    public void updateIdNo(Long patientId, String idNo) {
        Patient patient = patientRepository.get(patientId);
        patient.setIdCard(idNo);
        this.update(patient);
    }

    @Override
    public Map<Long, Boolean> existPersonalByDoctorIds(Long patientId, List<Long> doctorIdList) {
        Map<Long, Boolean> map = new HashMap<>();
        for (Long doctorId : doctorIdList) {
            map.put(doctorId, false);
        }
        String queryStr = StringUtil.convertCollection(doctorIdList);
        // 如果查询一个字段的话，那所有的值会放到第一个object数组中，不会创建多个数组
        List<PatientPersonDoctor> attends = patientPersonDoctorRepository.findByPersonPKPatientIdAndPersonPKDoctorIdIn(patientId, doctorIdList);
        if (attends != null && !attends.isEmpty()) {
            for (PatientPersonDoctor column : attends) {
                Long doctorId = column.getPersonPK().getDoctorId();
                map.put(doctorId, true);
            }
        }
        return map;
    }

    @Override
    public Patient get(Long id) {
        return patientRepository.get(id);
    }

    @Override
    public Patient save(Patient patient) {
        return patientRepository.saveOrUpdate(patient);
    }

    @Override
    public Patient saveOrUpdate(Patient patient) {
        return patientRepository.saveOrUpdate(patient);
    }

    @Override
    public Patient getPatientByMiniOpenId(String miniOpenId) {
        return patientRepository.findFirstByMiniOpenId(miniOpenId);
    }
}
